﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TableParsers;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace SpeakupBackend.Stats
{
    [Serializable]
    public class PersonalStats: INotifyPropertyChanged
    {
        public int Level { get; private set; }
        public int Unit { get; private set; }

        private LevelResultsTable m_levelResults = new LevelResultsTable();
        public ReadOnlyCollection<LevelResultsEntry> LevelResults
        {
            get
            {
                return m_levelResults.AsReadOnly();
            }
        }

        private UnitResultsTable m_unitResults = new UnitResultsTable();
        public ReadOnlyCollection<UnitResultsEntry> UnitResults
        {
            get
            {
                return m_unitResults.AsReadOnly();
            }
        }    

        public PersonalStats()
        {
            Level = 1;
            Unit = 1;
        }

        #region Fetch functionality

        public static PersonalStats Fetch(WebLayer.LoginToken loginToken)
        {
            WebPageParser.WebPageCache pageCache = new WebPageParser.WebPageCache();
            pageCache.LoginToken = loginToken;

            return Fetch(pageCache);
        }

        public static PersonalStats Fetch(WebPageParser.WebPageCache pageCache)
        {
            PersonalStats stats = new PersonalStats();

            ResultsTable resultsTable = ResultsTable.Fetch(pageCache);
            stats.m_levelResults = LevelResultsTable.Create(resultsTable);
            stats.m_unitResults = UnitResultsTable.Create(resultsTable);

            LevelAndUnit levelAndUnit = LevelAndUnit.Fetch(pageCache);
            stats.Level = levelAndUnit.Level;
            stats.Unit = levelAndUnit.Unit;
            return stats;
        }

        #endregion

        private void UpdateFrom(PersonalStats source)
        {
            this.m_levelResults = source.m_levelResults;
            this.m_unitResults = source.m_unitResults;
            this.Level = source.Level;
            this.Unit = source.Unit;

            OnPropertyChanged("");
        }

        public void Refresh(WebLayer.LoginToken loginToken)
        {
            UpdateFrom(Fetch(loginToken));
        }

        public void Refresh(WebPageParser.WebPageCache pageCache)
        {
            UpdateFrom(Fetch(pageCache));
        }

        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }        

        #region Persistency
        
        static public PersonalStats Load(String fileName)
        {
            IFormatter formatter = new BinaryFormatter();
            PersonalStats stats = null;
            using (FileStream s = File.OpenRead(fileName))
            {
                stats = (PersonalStats)formatter.Deserialize(s);
            }

            return stats;
        }       
        
        public void Reload(String fileName)
        {            
            PersonalStats stats = PersonalStats.Load(fileName);
            UpdateFrom(stats);
        }        

        public void Save(String fileName)
        {
            IFormatter formatter = new BinaryFormatter();
            using (FileStream s = File.Create(fileName))
            {
                formatter.Serialize(s, this);
            }
        }       

        #endregion
    }
}
